#pragma once
#include "Comm.h"
#include "Buffer.h"
#define COMMTYPE_MAX_SIZE	0x7FFFFFFF

namespace COMM
{
	class COMM_API CommType
	{
	public:
		static const CommType Void;
		static const CommType Null;
		static const CommType Error;

		enum ValueType
		{
			CT_VOID = 0,	//void
			CT_POINTER,		//pointer
			CT_BUFFER,		//buffer
			CT_STRING,		//string
			CT_FLOAT,		//float
			CT_DOUBLE,		//double

			CT_SHORT,		//short
			CT_INT,			//int
			CT_LONG,		//long
			CT_LONGLONG,	//long long

			CT_USHORT,		//unsigned short
			CT_UINT,		//unsigned int
			CT_ULONG,		//unsigned long
			CT_ULONGLONG,	//unsigned long long
			CT_MAX
		};

		CommType(void);
		CommType(const void* ptr);
		CommType(const void* buffer, size_t size);
		CommType(const Buffer& buffer);
		CommType(const char* str);
		CommType(const String& str);
		CommType(float f);
		CommType(double lf);
		CommType(short s);
		CommType(int i);
		CommType(long l);
		CommType(long long ll);
		CommType(unsigned short us);
		CommType(unsigned int ui);
		CommType(unsigned long ul);
		CommType(unsigned long long ull);
		CommType(const CommType& rhs);
		CommType& operator=(const CommType& rhs);
		~CommType();

		ValueType Type() const;
		const char* TypeString() const;

		// get internal memory address.
		void* get();
		const void* get() const;
		// get internal memory size.
		size_t size() const;
		// compare.
		bool Equal(const CommType& rhs) const;
		bool IsVoid() const;
		bool IsNull() const;
		bool IsError() const;
		bool operator==(const CommType& rhs) const;
		bool operator!=(const CommType& rhs) const;
	
		operator String() const;
		operator Buffer() const;
		operator void*();
		operator const void*() const;
		operator char*();
		operator const char*() const;
		operator float() const;
		operator double() const;
		operator short() const;
		operator int() const;
		operator long() const;
		operator long long() const;
		operator unsigned short() const;
		operator unsigned int() const;
		operator unsigned long() const;
		operator unsigned long long() const;
		// convert variant type to string.
		String ToString() const;

		// serialize and de-serialize.
		// "void*,long,unsigned long,size_t" have different size on 32/64bit system.
		// do not use these types in different system.
		Buffer Serialize() const;
		static CommType Deserialize(const void* buffer, size_t size);
		static CommType Deserialize(const Buffer& buffer);
		
	private:
		void* ptr() const;
		void Copy(const void* buffer, size_t size, ValueType type=CT_BUFFER);
		void Copy(const CommType& rhs);
		void Release();
		
		union
		{
			char* p;
			float f;
			double lf;
			short s;
			int i;
			long l;
			long long ll;
			unsigned short us;
			unsigned int ui;
			unsigned long ul;
			unsigned long long ull;
		}m_v;
		ValueType m_t;
		size_t m_p_size;

	};

}

